var btnConn = document.querySelector('button#connectServerId')
var btnLeave = document.querySelector('button#leaveId')
var localStreamVideo = document.querySelector('video#localVideoId')
var remoteStreamVideo = document.querySelector('video#remoteVideoId')

var localStream = null
var roomId = '111111'
var socket = null
var state = 'init'
var pc = null

//如果返回的是false说明当前操作系统是手机端，如果返回的是true则说明当前的操作系统是电脑端
function IsPC() {
	var userAgentInfo = navigator.userAgent
	var Agents = ["Android", "iPhone","SymbianOS", "Windows Phone","iPad", "iPod"]
	var flag = true

	for (var v = 0; v < Agents.length; v++) {
		if (userAgentInfo.indexOf(Agents[v]) > 0) {
			flag = false
			break
		}
	}

	return flag
}

function sendMessage(roomId,data) {
    // console.log('send p2p message :',roomId,data)

    if (socket) {
        socket.emit('message',roomId,data)
    }
}

function handleOfferError(err) {
    console.error('Failed to get Offer!',err)
}

function getOffer(desc) {
    pc.setLocalDescription(desc)
    sendMessage(roomId,desc)
}

function getAnswer(desc) {
    pc.setLocalDescription(desc)
    sendMessage(roomId,desc)
}

function handleAnswerError(err) {
    console.error('Failed to get Answer!',err)
}

// 只有主动发起方才能调用
function call() {
    if (state === 'joined_conn' && pc) {
        // 表明接收远端的音频跟视频
        const options = {
            offerToReceiveAudio: true,
            offerToReceiveVideo: true
        }

        pc.createOffer(options).then(getOffer).catch(handleOfferError)
    }
}

function conn() {
    // socket = io("http://localhost:3000", {
    //   withCredentials: false, // 必须和服务端 cors.credentials 匹配
    //   transports: ["websocket", "polling"]
    // })
    socket = io.connect()

    socket.on('joined',function(roomId,id) {
        console.log('receive joined message:',roomId,id)

        state = 'joined'
        createPeerConnection()

        btnConn.disabled = true
        btnLeave.disabled = false

        console.log('receive joined message state：',state)
    })

    socket.on('otherjoin',function(roomId,id) {
        console.log('receive otherjoin message:',roomId,id)

        if (state == 'joined_unbind') {
            createPeerConnection()
        }

        state = 'joined_conn'
        // 媒体协商
        call()

        console.log('receive otherjoin message state：',state)
    })

    socket.on('full',function(roomId,id) {
        console.log('receive full message:',roomId,id)
        state = 'leaved'
        console.log('receive full message state：',state)
        socket.disconnect()

        alert('the room is full!')
        
        btnConn.disabled = false
        btnLeave.disabled = true
    })

    // 自己主动离开了
    socket.on('leaved',function(roomId,id) {
        console.log('receive leaved message:',roomId,id)
        state = 'leaved'
        console.log('receive leaved message state：',state)

        socket.disconnect()

        btnConn.disabled = false
        btnLeave.disabled = true
    })

    // 对端离开了
    socket.on('bye',function(roomId,id) {
        console.log('receive bye message:',roomId,id)
        state = 'joined_unbind'
        closePeerConnection()
        console.log('receive bye message state：',state)
    })

    socket.on('message',function(roomId,data) {
        console.log('receive client message:',roomId,data)
        // 媒体协商
        if (data) {
            if (data.type === 'offer') { // 收到对端的offer
                pc.setRemoteDescription(new RTCSessionDescription(data))

                // 创建answer并且发送给对端
                pc.createAnswer().then(getAnswer).catch(handleAnswerError)
            } else if (data.type === 'answer') {
                pc.setRemoteDescription(new RTCSessionDescription(data))
            } else if (data.type === 'candidate') {
                const candidate = new RTCIceCandidate({
                    sdpMLineIndex: data.label,
                    candidate: data.candidate
                })

                console.log('---candidate---',candidate)

                // 加入本端，接下来就要进行连接性检测了
                pc.addIceCandidate(candidate)
            } else {
                console.error('the message is invalid！',data)
            }
        }
    })

    socket.emit('join',roomId)
}

function createPeerConnection() {
    console.log('create RTCPeerConnection!')
    if (!pc) {
        var pcConfig = {
            'iceServers': [
                {
                    'urls': 'stun:47.115.92.79:3478',
                    'username': 'duanzihuang',
                    'credential': '123456'
                }
                // { urls: 'stun:stun.l.google.com:19302' }
            ]
        }

        pc = new RTCPeerConnection(pcConfig)
        
        pc.onicecandidate = e => {
            if (e.candidate) {
                // 把收集到的candidate发送给对端
                // console.log('find an new candidate',e.candidate)

                sendMessage(roomId,{
                    type: 'candidate',
                    label: e.candidate.sdpMLineIndex,
                    id: e.candidate.sdpMid,
                    candidate: e.candidate.candidate
                })
            } else {
				console.log('this is the end candidate')
			}
        }

        // 收到对端发送过来的视频流等
        pc.ontrack = e => {
            console.log("Received track event:", e)
            if (e.streams && e.streams.length > 0) {
                console.log("Setting remote stream with", e.streams.length, "tracks")
                remoteStreamVideo.srcObject = e.streams[0]
            } else if (e.track) {
                console.log("Creating new stream from track")
                const stream = new MediaStream()
                stream.addTrack(e.track)
                remoteStreamVideo.srcObject = stream
            }
            
            // 确保视频元素播放
            remoteStreamVideo.play().catch(err => {
                console.error("Error playing remote video:", err)
            })
        }
    }

    if (localStream) {
        // localStream.getTracks().forEach(track=>{
        //     pc.addTrack(track)
        // })
        const videoTracks = localStream.getVideoTracks()
        const audioTracks = localStream.getAudioTracks()
        
        console.log('Adding tracks - Video:', videoTracks.length, 'Audio:', audioTracks.length)
        
        // 明确添加每个轨道
        videoTracks.forEach(track => pc.addTrack(track, localStream))
        audioTracks.forEach(track => pc.addTrack(track, localStream))
    }
}

function closePeerConnection() {
    console.log('close RTCPeerConnection!')
    if (pc) {
        pc.close()
        pc = null
    }
}

function getMediaStream(stream){
    localStream = stream
    localStreamVideo.srcObject = stream

    // 连接到信令服务器
    conn()
}

function handleError(err) {
    if (err) {
        console.error('Failed to get Media Stream:',err)
    }
}

function getDeskStream(stream) {
    localStream = stream
    localStreamVideo.srcObject = stream
    // 连接到信令服务器
    conn()
}

function start() {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
        console.error('the getUserMedia is not supported!')
        return
    } 

    if (IsPC()) {
        navigator.mediaDevices.getDisplayMedia({video: true})
			.then(getDeskStream)
			.catch(handleError)
    } else {
        var constraints = {
            video: true,
            audio: true
        }
        navigator.mediaDevices.getUserMedia(constraints).then(getMediaStream).catch(handleError)
    }
}

function closeLocalMedia() {
    if (localStream && localStream.getTracks()) {
        localStream.getTracks().forEach(track=> {
            track.stop()
        })
    }

    localStream = null
}

btnConn.onclick = () => {
    // 开启本地音视频
    start()
}

btnLeave.onclick = () => {
    if (socket) {
        socket.emit('leave',roomId,socket.id)
    }

    // 清理资源
    closePeerConnection()
    closeLocalMedia()

    btnConn.disabled = false
    btnLeave.disabled = true
}